home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* ascf 3
- /* SUMMARY
- /* stdio-like ascii filter
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* ascii filtering
- /* SYNOPSIS
- /* #include <stdio.h>
- /* #include "ascf.h"
- /*
- /* FILE *ascopen(name,mode)
- /* char *name;
- /* char *mode;
- /*
- /* int ascget(fp)
- /* FILE *fp;
- /*
- /* ascpbk(c,fp)
- /* int c;
- /* FILE *fp;
- /*
- /* char *ascgets(buf,buflen,fp);
- /* char *buf;
- /* int buflen;
- /* FILE *fp;
- /*
- /* int ascclose(fp)
- /* FILE *fp;
- /* DESCRIPTION
- /* The functions in this module provide filtered stream i/o for
- /* textfiles produced by word processors. Their calling sequence
- /* has been modelled after the standard i/o library routines.
- /*
- /* The following mappings are done: cr/lf, cr, lf, lf/cr are
- /* replaced by newline; all high bits are stripped off; wordstar
- /* hyphens are converted to normal hyphens. Except for tabs and backspace,
- /* control characters are filtered out. A newline
- /* character is appended to the last line of a file if that file
- /* does not terminate on a newline character.
- /*
- /* ascopen() is the analogon of fopen(3), ascget() returns the next
- /* character in the filtered input stream, and ascclose() closes
- /* the stream. ascget() is a macro. A "feature" of the ascopen()
- /* function is that it interprets a file name "-" as standard
- /* input (and ignores the mode argument in that case).
- /*
- /* ascpbk() pushes back the last character read with ascget().
- /*
- /* ascgets() reads one string and strips trailing newline or carriage
- /* return characters. A null pointer is returned if no string could
- /* be read, otherwise ascgets() returns a pointer to the buffer.
- /* SEE ALSO
- /* stdio(3) standard i/o library interface.
- /* DIAGNOSTICS
- /* ascopen() returns a null pointer on failure; ascget() returns
- /* the value EOF when the end of a stream is reached. ascclose()
- /* returns whatever fclose() returns.
- /* BUGS
- /* Actually works well with wordstar or clean ascii files only.
- /*
- /* Only "r" modes are supported.
- /*
- /* There is no way to seek() a filtered stream.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Mon Jul 6 16:03:41 GMT+1:00 1987
- /* LAST MODIFICATION
- /* 90/01/22 13:01:14
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
- #include <ctype.h>
-
- #include "defs.h"
- #include "ascf.h"
-
- /* some systems do not define _NFILE in stdio.h; not that they should, but.. */
-
- #ifndef _NFILE
- # include <sys/param.h> /* maybe we are a sun */
- # ifdef NOFILE
- # define _NFILE NOFILE
- # else
- "ERROR: cannot get max nr of open stdio streams"
- # endif
- #endif
-
- #define CTL(x) ((x)^0100) /* ASCII control characters */
-
- #ifdef MSDOS
- #include <fcntl.h> /* to turn cr/lf mapping off */
- #endif
-
- public Asc asc[_NFILE]; /* one filter structure per file */
-
- /* ascopen - open stream, initialize intermediate buffer */
-
- public FILE *ascopen(file,mode)
- char *file,*mode;
- {
- register FILE *fp;
-
- if (*mode != 'r') /* Cannot do filtered writes */
- return(0);
-
- if (fp = (strcmp(file, "-") ? fopen(file,mode) : stdin)) {
- register Asc *ap = asc+fileno(fp);
- if (ap->buf = malloc(BUFSIZ)) { /* if buffer available */
- ap->cnt = 0; /* init buffer count */
- ap->nlf = 0; /* no newline appended yet */
- #ifdef O_BINARY
- setmode(fileno(fp),O_BINARY);
- #endif
- } else {
- (void) fclose(fp); /* no room for that buffer */
- fp = 0;
- }
- }
- return(fp);
- }
-
- /* ascclose - release intermediate buffer and close the stream */
-
- public int ascclose(fp)
- register FILE *fp;
- {
- free(asc[fileno(fp)].buf);
- return(fclose(fp));
- }
-
- /* ascbuf - the actual filter, fill one new buffer of text */
-
- public int ascbuf(fp)
- FILE *fp;
- {
- register Asc *ap = asc+fileno(fp); /* intermediate buffer access */
- register char *cp = ap->buf; /* initialize write pointer */
- register int c; /* single-character input buffer */
- int d; /* look-ahead character */
-
- while (cp < ap->buf+BUFSIZ && (c = getc(fp)) != EOF) {
- if ((c &= 0177) == ' ' || isprint(c) || c == '\t' || c == '\b') {
- *cp++ = c; /* accept character */
- } else if ((c == '\r' && ((d = getc(fp)) == '\n' || (ungetc(d,fp),1)))
- || (c == '\n' && ((d = getc(fp)) == '\r' || (ungetc(d,fp),1)))) {
- *cp++ = '\n'; /* terminate line */
- } else if (c == CTL('_')) {
- *cp++ = '-'; /* wordstar hyphen */
- } else {
- continue; /* ignore other characters */
- }
- }
- if (ap->cnt = cp-ap->buf) { /* anything in the buffer? */
- ap->ptr = ap->buf; /* yes, set read pointer */
- ap->nlf = cp[-1]; /* remember last character */
- return(ascget(fp)); /* and return first character */
- } else if (ap->nlf != '\n') { /* make sure file ends with \n */
- return(ap->nlf = '\n'); /* append newline */
- } else { /* now we're really done */
- return(EOF); /* that's it. */
- }
- }
-
- /* ascgets - read string, strip crlf */
-
- public char *ascgets(buf, buflen, fp)
- char *buf;
- int buflen;
- FILE *fp;
- {
- register int c;
- register char *cp = buf;
- register char *ce = buf + buflen - 1;
-
- while ((c = ascget(fp)) != EOF) {
- if (c == '\n') { /* suppress crlf */
- break;
- } else if (cp < ce) { /* will fit */
- *cp++ = c;
- } else { /* push back */
- ascpbk(c, fp);
- break;
- }
- }
- *cp = 0;
- return ((c == EOF && cp == buf) ? 0 : buf);
- }
-